package com.tyk.bookstore.back.storage.controller;


import cn.dev33.satoken.annotation.SaCheckPermission;
import com.tyk.bookstore.back.common.core.excel.ExcelManager;
import com.tyk.bookstore.back.common.core.model.page.PageVo;
import com.tyk.bookstore.back.common.core.model.result.R;
import com.tyk.bookstore.back.common.core.model.type.BinVo;
import com.tyk.bookstore.back.common.core.model.type.SuggestionQuery;
import com.tyk.bookstore.back.storage.manager.excel.constant.ExcelConstant;
import com.tyk.bookstore.back.storage.manager.excel.model.WarehouseExcelVo;
import com.tyk.bookstore.back.storage.model.query.WarehouseAddQuery;
import com.tyk.bookstore.back.storage.model.query.WarehousePageQuery;
import com.tyk.bookstore.back.storage.model.query.WarehouseUpdateQuery;
import com.tyk.bookstore.back.storage.model.vo.WarehousePageVo;
import com.tyk.bookstore.back.storage.model.vo.WarehouseVo;
import com.tyk.bookstore.back.storage.service.WarehouseService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Set;

/**
 * @author tyk
 * @description 仓库管理
 */
@RequestMapping({"api/storage/warehouse"})
@Tag(name = "仓储管理/仓库管理", description = "仓库管理")
@RestController
@RequiredArgsConstructor
public class WarehouseController {
    private final WarehouseService warehouseService;
    private final ExcelManager<WarehouseExcelVo> excelManager;


    @Operation(summary = "获取仓库详情", description = "获取仓库详情")
    @SaCheckPermission("storage:warehouse:get")
    @GetMapping({"{id}"})
    public R<WarehouseVo> getById(
            @Schema(description = "仓库ID") @NotNull @Min(1)
            @PathVariable Long id
    ) {
        return R.ok(warehouseService.getById(id));
    }


    @Operation(summary = "分页查询仓库", description = "分页查询仓库")
    @SaCheckPermission("storage:warehouse:page")
    @GetMapping({"page"})
    public R<WarehousePageVo> getPage(
            @Validated @ParameterObject WarehousePageQuery query,
            BindingResult br
    ) {
        return br.hasErrors() ? R.ok(PageVo.instance(WarehousePageVo.class)) : R.ok(warehouseService.getPage(query));
    }

    @Operation(summary = "仓库搜索建议列表", description = "仓库搜索建议列表")
    @SaCheckPermission("storage:warehouse:suggest")
    @GetMapping({"suggest"})
    public R<List<BinVo>> getSuggestionList(
            @Validated @ParameterObject SuggestionQuery query
    ) {
        return R.ok(warehouseService.getSuggestionList(query));
    }


    @Operation(summary = "添加仓库", description = "添加仓库")
    @SaCheckPermission("storage:warehouse:add")
    @PostMapping
    public R<Object> add(
            @Validated @RequestBody WarehouseAddQuery query
    ) {
        warehouseService.add(query);
        return R.ok();
    }

    @Operation(summary = "更新仓库", description = "更新仓库")
    @SaCheckPermission("storage:warehouse:update")
    @PutMapping
    public R<Object> updateById(
            @Validated @RequestBody WarehouseUpdateQuery query
    ) {
        warehouseService.updateById(query);
        return R.ok();
    }


    @Operation(summary = "删除仓库", description = "删除仓库")
    @SaCheckPermission("storage:warehouse:delete")
    @DeleteMapping({"{id}"})
    public R<Object> deleteById(
            @Schema(description = "仓库ID") @NotNull @Min(1)
            @PathVariable Long id
    ) {
        warehouseService.deleteById(id);
        return R.ok();
    }

    @Operation(summary = "批量删除仓库", description = "批量删除仓库")
    @SaCheckPermission("storage:warehouse:delete")
    @DeleteMapping
    public R<Object> deleteBatchByIdSet(
            @Schema(description = "仓库ID列表") @NotNull @NotEmpty Set<Long> idList
    ) {
        warehouseService.deleteBatchByIdSet(idList);
        return R.ok();
    }

    @Operation(summary = "导出Excel", description = "导出Excel")
    @SaCheckPermission("storage:warehouse:excel:download")
    @GetMapping("excel")
    public void downloadExcel(WarehousePageQuery query, HttpServletResponse resp) {
        excelManager.write(
                warehouseService.getWarehouseExcelVoList(query),
                ExcelConstant.WAREHOUSE_FILE_NAME,
                ExcelConstant.WAREHOUSE_SHEET,
                resp
        );
    }


    @Operation(summary = "导入Excel", description = "导入Excel")
    @SaCheckPermission("storage:warehouse:excel:upload")
    @PostMapping("excel")
    public R<Object> uploadExcel(MultipartFile file) {
        excelManager.save(
                file,
                warehouseService::saveWarehouseExcelVoList
        );
        return R.ok();
    }


    @Operation(summary = "下载Excel模板", description = "下载Excel模板")
//    @SaCheckPermission("storage:warehouse:excel:template")
    @GetMapping("excel/template")
    public void excelTemplate(HttpServletResponse resp) {
        excelManager.template(
                ExcelConstant.WAREHOUSE_TEMPLATE,
                List.of("名字", "所在区域Code", "详细地址", "负责人ID", "寄件方姓名", "寄件方地址", "寄件方电话"),
                resp
        );
    }
}
